home *** CD-ROM | disk | FTP | other *** search
- /* read.c - read a TTDDD file and fill the structures
- * - written by Glenn M. Lewis - 7/19/91
- * - Altered for Imagine 3.0 support - Rob Hounsell - Sept.94
- */
-
- static char rcs_id[] = "$Id: read.c,v 1.34 1995/02/01 22:21:43 glewis Exp glewis $";
-
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include "t3dlib.h"
- #ifdef __STDC__
- #include <stdlib.h>
- #include <strings.h>
- #include "read_protos.h"
- #endif
-
- static void process_INFO();
- static void process_OBJ();
- static void process_ISTG();
- static OBJECT *process_EXTR();
- static void process_DESC();
- static OBJECT *process_MXTR();
- static void desc_copy();
- static void malloc_arrays();
- extern int verbose_flag;
- extern int already_read_header; /* A hack to include characters */
- extern unsigned char header_storage[]; /* that were already read in */
- extern void insert_into_sorted_list();
-
- #define MAXLINE 1024
- #define get_UBYTE (UBYTE)get_num
- #define get_UWORD (UWORD)get_num
- #define get_ULONG (ULONG)get_num
-
- static char strin[MAXLINE+1], ps[MAXLINE+1];
- static UBYTE defclst[3], defrlst[3], deftlst[3], defspc1[3];
-
- /* Here are a few necessary utilities */
-
- static void warn(curline)
- int curline;
- {
- fprintf(stderr, "WARNING: Line %d: ", curline);
- }
-
- static void parse_effect_data(name)
- register char *name;
- {
- register char *c = &strin[0];
- register int i;
- int quote = 0;
-
- /* get all chars in string, skipping first and last quote */
-
- while (*c==' ') c++; /* Skip over leading spaces */
- for (i=0; *c; i++,c++) {
- if (*c == '\"') { /* Chop off quotes, ignore spaces */
- if (!quote) { /* first quote */
- quote=1;
- i--; /* Don't want i to increment */
- continue;
- } else
- /* Check for Second quote at END of string. Stop reading string */
- if (c[1] == '\0') break;
- }
- *name++ = *c;
- }
- *name = '\0'; /* Truncate the puppy */
- /* Now, delete the command from 'strin' */
- while (*c && *c!=' ') c++; /* Skip the end of the command */
- while (*c==' ') c++; /* Skip mid-word spacing */
- strcpy(strin, c); /* Chop off front of line */
- }
-
- static void parse_word(name, lim, up) /* Get next word, optionally limit # of chars */
- register char *name;
- int lim, up;
- {
- register char *c = &strin[0];
- register int i;
- int quote = 0;
-
- while (*c==' ') c++; /* Skip over leading spaces */
- for (i=0; *c; i++,c++) {
- if (lim && i>=lim) break; /* No more characters desired */
- if (*c == '\"') { /* Chop off quotes, ignore spaces */
- if (quote) break; /* Second quote. Stop reading string */
- quote=1;
- i--; /* Don't want i to increment */
- continue;
- }
- if (up && !quote && islower(*c)) *name++ = toupper(*c);
- else {
- if (!quote && *c==' ') break; /* End of the line */
- *name++ = *c; /* Don't modify original case */
- }
- }
- *name = '\0'; /* Truncate the puppy */
- /* Now, delete the command from 'strin' */
- while (*c && *c!=' ') c++; /* Skip the end of the command */
- while (*c==' ') c++; /* Skip mid-word spacing */
- strcpy(strin, c); /* Chop off front of line */
- }
-
- static int get_line(strin, w)
- register char *strin;
- WORLD *w;
- {
- static int comment = 0;
- int quote = 0, start;
- register char *c;
-
- GET_MORE:
- if (comment) start = 0; else start = -1;
- if (fgets(&strin[already_read_header], MAXLINE, w->inp) == NULL) {
- already_read_header = 0;
- if (comment)
- fprintf(stderr, "WARNING: Line %d: Unterminated comment.\n",w->cur_line);
- return(0); /* EOF */
- }
- already_read_header = 0;
- w->cur_line++;
- for (c=strin; *c; c++) {
- if (*c=='/' && c[1]=='*') { /* Begin of comment */
- if (!quote) {
- if (!comment++) { /* First comment */
- start = (int)(c-strin);
- }
- }
- } else
- if (*c=='*' && c[1]=='/') { /* End of comment */
- if (!quote) {
- comment--;
- if (comment<0) {
- fprintf(stderr, "ERROR! '*/' before '/*'\n*** ABORT ***\n");
- exit(20);
- }
- if (!comment) { /* Chop off front of line */
- strcpy(strin, c+2);
- c = strin-1; /* Pointer will increment */
- }
- }
- } else
- if (*c=='%') { /* Line comment */
- if (!(quote || comment)) {
- *c = '\0'; /* Terminate line */
- break;
- }
- } else
-
- /* The SPFX line contains uuencoded information, including quotes! */
- /* So, don't clear the quote flag unless the found quote is followed */
- /* by either a space or a newline character. Spaces are not found */
- /* in a uuencoded string. */
-
- if ((*c =='\"') && (!quote)) { /* Starting Quote */
- if (!comment) quote=1-quote; /* Toggle flag */
- } else
- if ((*c =='\"') && ((c[1] == ' ') || (c[1] == '\n'))) { /* End Quote */
- if (!comment) quote=1-quote; /* Toggle flag */
- } else
- if (*c == '\t') *c = ' '; /* Change tabs to spaces */
- else
- if (!quote && (*c=='[' || *c==']' || *c=='=')) *c = ' ';
- if (*c == '\n') { *c = '\0'; break; }
- }
- if (comment) strin[start] = '\0'; /* Chop off comment */
- /* Skip leading white space to see if this line contains anything */
- for (c=strin; *c==' '; c++) ;
- if (!*c) goto GET_MORE;
- return(1);
- }
-
- static int valid_num;
-
- static long get_num()
- {
- long val = 0;
- char neg = ' ';
- register char *c = &strin[0];
-
- valid_num = 0;
- while (*c == ' ') c++; /* Skip leading space */
- if (*c == '-') neg = *c++; /* Save the negation */
- if (!isdigit(*c)) return(0L);
- while (*c && isdigit(*c))
- val = (val*10) + (*c++ - '0');
- while (*c == ' ') c++; /* Skip trailing space */
- strcpy(strin, c); /* Chop off number */
- valid_num = 1;
- return((neg=='-' ? -val : val));
- }
-
- static int valid_FRACT;
-
- static double get_FRACT()
- {
- register long whole, expo;
- register char *s = &strin[0];
- char neg=' ', negexp=' ';
- double f, frac, place;
-
- valid_FRACT = 0;
- whole = expo = 0;
- while (*s == ' ') s++;
- if (*s == '-') neg = *s++;
- if (!isdigit(*s) && *s!='.') return(0L); /* Invalid FRACT */
- while (*s && isdigit(*s)) /* Handle float before decimal point */
- whole = (whole * 10) + (*s++ - '0');
- if (*s == '.') { /* Handle float after decimal point */
- s++;
- frac = 0.0;
- for (place=10.0; *s && isdigit(*s); place*=10.0)
- frac += (*s++ - '0')/place;
- f = (double)whole + frac;
- } else f = (double)whole;
- if (*s == 'e' || *s == 'E') { /* Support exponential notation */
- s++;
- if (*s=='-' || *s=='+') negexp = *s++;
- while (*s && isdigit(*s)) expo = (expo*10) + (*s++ - '0');
- if (negexp=='-') while (expo--) f/=10.0;
- else while (expo--) f*=10.0;
- }
- while (*s == ' ') s++;
- strcpy(strin, s);
- valid_FRACT = 1;
- return((neg=='-' ? -f : f));
- }
-
- static void stage_RGB(st)
- XYZ_st *st;
- {
- register char *c = &strin[0];
- register int i, flag, cnt;
-
- flag = 0; /* If they use 'R','G', or 'B', they must continue to use it */
- /* On the other hand, if they give only a single parameter, then it applies to all */
- cnt = 0;
- for (i=0; i<3; i++) {
- if (*c=='r' || *c=='R') /* If !valid, it's an ERROR! */
- { *c=' '; st->x = get_FRACT(); if (valid_FRACT) flag=1; }
- else
- if (*c=='g' || *c=='G')
- { *c=' '; st->y = get_FRACT(); if (valid_FRACT) flag=1; }
- else
- if (*c=='b' || *c=='B')
- { *c=' '; st->z = get_FRACT(); if (valid_FRACT) flag=1; }
- else if (!flag) {
- if (i==0) st->x = get_FRACT();
- else if (i==1) st->y = get_FRACT();
- else st->z = get_FRACT();
- if (valid_FRACT) cnt++;
- }
- }
- if (!flag && cnt==1) { /* Copy value into other two elements */
- st->y = st->z = st->x;
- }
- }
-
- static void stuff_XYZ(st)
- XYZ_st *st;
- {
- register char *c = &strin[0];
- register int i, flag, cnt;
-
- flag = 0; /* If they use 'X','Y', or 'Z', they must continue to use it */
- /* On the other hand, if they give only a single parameter, then it applies to all */
- cnt = 0;
- for (i=0; i<3; i++) {
- if (*c=='x' || *c=='X') /* If !valid, it's an ERROR! */
- { *c=' '; st->x = get_FRACT(); if (valid_FRACT) flag=1; }
- else
- if (*c=='y' || *c=='Y')
- { *c=' '; st->y = get_FRACT(); if (valid_FRACT) flag=1; }
- else
- if (*c=='z' || *c=='Z')
- { *c=' '; st->z = get_FRACT(); if (valid_FRACT) flag=1; }
- else if (!flag) {
- if (i==0) st->x = get_FRACT();
- else if (i==1) st->y = get_FRACT();
- else st->z = get_FRACT();
- if (valid_FRACT) cnt++;
- }
- }
- if (!flag && cnt==1) { /* Copy value into other two elements */
- st->y = st->z = st->x;
- }
- }
-
- static void stuff_RGB(st)
- RGB_st *st;
- {
- register char *c = &strin[0];
- register int i, flag, cnt;
-
- flag = 0; /* If they use 'R','G', or 'B', they must continue to use it */
- /* On the other hand, if they give only a single parameter, then it applies to all */
- cnt = 0;
- for (i=0; i<3; i++) {
- if (*c=='r' || *c=='R') /* If !valid, it's an ERROR! */
- { *c=' '; st->r = get_UBYTE(); if (valid_num) flag=1; }
- else
- if (*c=='g' || *c=='G')
- { *c=' '; st->g = get_UBYTE(); if (valid_num) flag=1; }
- else
- if (*c=='b' || *c=='B')
- { *c=' '; st->b = get_UBYTE(); if (valid_num) flag=1; }
- else if (!flag) {
- if (i==0) st->r = get_UBYTE();
- else if (i==1) st->g = get_UBYTE();
- else st->b = get_UBYTE();
- if (valid_num) cnt++;
- }
- }
- if (!flag && cnt==1) { /* Copy value into other two elements */
- st->g = st->b = st->r;
- }
- }
-
- /********************/
- /* The MAIN section */
- /********************/
-
- WORLD *read_TTDDD(file)
- FILE *file;
- {
- char name[5];
- WORLD *world;
-
- if (!file) return(0L); /* File not open */
-
- if (!(world = (WORLD*)malloc(sizeof(WORLD)))) { OUT_MEM("WORLD"); }
- bzero((char*)world, sizeof(WORLD));
- world->inp = file;
-
- if (already_read_header) /* Copy the data into the "strin" */
- strncpy(strin, header_storage, already_read_header);
-
- /* Here is the main loop: */
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* And chop it out of the string */
-
- if (strcmp(name, "INFO")==0) process_INFO(world);
- else if (strcmp(name, "OBJ") ==0) process_OBJ(world);
- else if (strcmp(name, "ISTG")==0) process_ISTG(world);
- else {
- fprintf(stderr, "Invalid chunk on line %d: '%s' (skipped)\n",
- world->cur_line, name);
- continue;
- }
- }
-
- /* All done. Close up shop. */
- return(world);
- }
-
- static void process_INFO(world)
- WORLD *world;
- {
- register INFO *info;
- register ULONG i;
- char this_level[MAXLINE], name[5];
-
- if (world->info) {
- fprintf(stderr, "Parse error: More than one INFO chunk!\n"); exit(-1); }
- if (!(info = world->info = (INFO*)malloc(sizeof(INFO)))) { OUT_MEM("INFO"); }
- bzero((char *)world->info, sizeof(INFO));
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'INFO'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- if (strcmp(name, "BRSH")==0) {
- i = get_UWORD();
- if (i<0 || i>7) fputs("BRSH error.\n", stderr);
- parse_word(ps, 0, 0);
- strncpy(info->brsh[i], ps, 80);
- info->brsh[i][80]='\0';
- } else
- if (strcmp(name, "STNC")==0) {
- i = get_UWORD();
- if (i<0 || i>7) fputs("STNC error.\n", stderr);
- parse_word(ps, 0, 0);
- strncpy(info->stnc[i], ps, 80);
- info->stnc[i][80]='\0';
- } else
- if (strcmp(name, "TXTR")==0) {
- i = get_UWORD();
- if (i<0 || i>7) fputs("TXTR error.\n", stderr);
- parse_word(ps, 0, 0);
- strncpy(info->txtr[i], ps, 80);
- info->txtr[i][80]='\0';
- } else
- if (strcmp(name, "OBSV")==0) {
- if (!info->obsv) info->obsv=(OBSV*)malloc(sizeof(OBSV));
- if (!info->obsv) { OUT_MEM("OBSV"); }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "CAME")==0) stuff_XYZ(&info->obsv->came);
- else if (strcmp(name, "ROTA")==0) stuff_XYZ(&info->obsv->rota);
- else if (strcmp(name, "FOCA")==0) info->obsv->foca = get_FRACT();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown OBSV field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "OTRK")==0) {
- parse_word(ps, 0, 0);
- strncpy(info->otrk, ps, 18);
- info->otrk[18]='\0';
- } else
- if (strcmp(name, "OSTR")==0) {
- if (!info->ostr) info->ostr=(STRY*)malloc(sizeof(STRY));
- if (!info->ostr) { OUT_MEM("OSTR"); }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "PATH")==0) parse_word(info->ostr->path, 18, 0);
- else if (strcmp(name, "TRAN")==0) stuff_XYZ(&info->ostr->tran);
- else if (strcmp(name, "ROTA")==0) stuff_XYZ(&info->ostr->rota);
- else if (strcmp(name, "SCAL")==0) stuff_XYZ(&info->ostr->scal);
- else
- if (strcmp(name, "INFO")==0) {
- info->ostr->info = 0;
- while (strin[0]) {
- parse_word(ps, 7, 1);
- if (strcmp(ps, "ABS_TRA")==0) info->ostr->info|=(1<<0);
- else if (strcmp(ps, "ABS_ROT")==0) info->ostr->info|=(1<<1);
- else if (strcmp(ps, "ABS_SCL")==0) info->ostr->info|=(1<<2);
- else if (strcmp(ps, "LOC_TRA")==0) info->ostr->info|=(1<<4);
- else if (strcmp(ps, "LOC_ROT")==0) info->ostr->info|=(1<<5);
- else if (strcmp(ps, "LOC_SCL")==0) info->ostr->info|=(1<<6);
- else if (strcmp(ps, "X_ALIGN")==0) info->ostr->info|=(1<<8);
- else if (strcmp(ps, "Y_ALIGN")==0) info->ostr->info|=(1<<9);
- else if (strcmp(ps, "Z_ALIGN")==0) info->ostr->info|=(1<<10);
- else if (strcmp(ps, "FOLLOW_")==0) info->ostr->info|=(1<<12);
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown OSTR INFO flag: '%s'\n",
- world->cur_line, ps);
- continue;
- }
- }
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown OSTR field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "FADE")==0) {
- if (!info->fade) info->fade=(FADE*)malloc(sizeof(FADE));
- if (!info->fade) { OUT_MEM("FADE"); }
- parse_word(ps, 6, 1); /* Get field */
- if (strcmp(ps, "FADEAT")==0) info->fade->at = get_FRACT();
- else if (strcmp(ps, "FADEBY")==0) info->fade->by = get_FRACT();
- else if (strcmp(ps, "FADETO")==0) stuff_RGB(&info->fade->to);
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown FADE field: '%s'\n",
- world->cur_line, ps);
- continue;
- }
- } else
- if (strcmp(name, "SKYC")==0) {
- if (!info->skyc) info->skyc=(SKYC*)malloc(sizeof(SKYC));
- if (!info->skyc) { OUT_MEM("SKYC"); }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "HORI")==0) stuff_RGB(&info->skyc->hori);
- else if (strcmp(name, "ZENI")==0) stuff_RGB(&info->skyc->zeni);
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown SKYC field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "AMBI")==0) {
- if (!info->ambi) info->ambi=(RGB_st*)malloc(sizeof(RGB_st));
- if (!info->ambi) { OUT_MEM("AMBI"); }
- stuff_RGB(info->ambi);
- } else
- if (strcmp(name, "GLB0")==0) {
- if (!info->glb0) info->glb0=(BYTE*)malloc(8*sizeof(BYTE));
- if (!info->glb0) { OUT_MEM("GLB0"); }
- i = get_ULONG(); /* Index into array */
- if (i>=0 && i<8) {
- info->glb0[i] = (BYTE) get_ULONG();
- } else
- fprintf(stderr, "WARNING: Line %d: Bad index: GLB0[%d] should be [0..7]\n", world->cur_line, i);
- } else if (strcmp(name, "END")==0) {
- parse_word(name, 4, 1);
- if (strcmp(name, "INFO")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END INFO' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'INFO Begin' and 'End INFO' quoted comments do not match\n", world->cur_line);
- break;
- } else if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown INFO sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
-
- OBJECT *create_object()
- {
- OBJECT *p;
- p = (OBJECT*)malloc(sizeof(OBJECT));
- if (!p) { OUT_MEM("Create"); }
- bzero((char*)p,sizeof(OBJECT));
- return(p);
- }
-
- static void process_OBJ(world)
- WORLD *world;
- {
- char this_level[MAXLINE], name[5];
- register OBJECT *p;
- int depth;
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'OBJ'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- depth=0;
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- if (strcmp(name, "EXTR")==0) {
- p = process_EXTR(create_object(), world);
- if (world->curobj) {
- world->curobj->next = p;
- p->parent = world->curobj->parent;
- } else {
- world->object = p;
- p->parent = 0;
- }
- world->curobj = p;
-
- /*
-
- Glenn:
- Here is the merging code. I also tried loading grouped objects into
- the detail editor, with similar results to what I was seeing when I was loading
- massive numbers of separate objects. Results are below, but I think this will
- complicate our lives considerably.
- Cheers,
- Charles
-
- ------------------------------------------------------------------------------
- Charles Congdon Oracle Corporation
- Special Projects 2580 SW 192nd Ave.
- Midrange Systems Group, DEC Products Division Aloha, OR 97006
- Office: (415) 506-6341 FAX: (415) 506-6341
- Internet: ccongdon@us.oracle.com Usenet: uunet!oracle!ccongdon
- ------------------------------------------------------------------------------
-
- MODIFICATIONS TO READ.C TO SUPPORT MXTR CHUNKS
- ==============================================
-
- Purpose:
-
- These routines allow the following construct:
-
- MXTR Begin
-
- EXTR Begin
- <etc>
- End EXTR
-
- EXTR Begin
- <etc>
- End EXTR
-
- EXTR Begin
- <etc>
- End EXTR
- :
- :
- :
-
- End MXTR
-
- Everything within the MXTR chunk is merged into one huge object. Over
- 750 objects have been merged with this code, resulting in objects with
- point, face, and edge counts in the mid-thousands (oh yes, and over
- 1400 subgroups!). I really mean "merge" here, not group.
-
- The last EXTR object in the list defines the face-insensitive
- attributes like hardness, specular, etc. for the entire mega object.
- NOTE: this implies that if you are merging two EXTR objects, one with
- a zero hardness, and one with a hardness of 255, then which ever is
- the last in the list before End MXTR defines the hardness for all. In
- short, don't merge objects with vastly differing face-insensitive
- attributes (for example, chrome and rubber).
-
- All component EXTR objects contribute to fill in the face-sensitive
- attributes (point, edge, face, color, reflect, and filter information)
- for the object (i.e. - all face-specific attributes are preserved for
- all faces of all component EXTR objects). Yes, that includes all
- subgroups defined for all component EXTR objects. Names of subgroups
- will be "mangled" with a counter to better let you identify who to
- change. I considered merging subgroups (since they can build up
- fast), but figured that is best for a future enhancement.
-
- Face-sensitive "attributes" that were thrown out entirely are textures
- and brushmaps. The reason is that these are limited to 4 per object.
- What do you do when you merge 1000 objects, each with three textures
- defined? Which 4 textures do you use? What should the texture axis
- positions be? How about the texture scale factors? In short, apply
- your textures to your merged object (using subgroups if you wish to
- restrict the scope) once you have loaded it into Imagine.
-
- Another limitation is that at present I do not support heirachical
- EXTR objects. If you look at the length of the code below, I think
- you will understand why. To do so, simply unroll the heirarchy into
- the master object. This will require an additional preprocessing step
- to properly calculate point, edge, and face counts, and some recursion
- in the main copying loop. NOTE: By not preserve I mean two things:
- 1) at present I only copy the parent of an EXTR object that is
- actually a group. 2) I don't try to build heirarchy into the merged
- object either.
-
- Why not *preserve* heirachies, you ask? Because Imagine reacts poorly
- to the creation of massive numbers of objects at a time. Loading any
- more than 100-300 objects at a time into the detail results in a wait
- that can stretch on for hours as Imagine sets up for fast access to
- these objects. The objects all happily draw in the tri-view window
- almost instantly, but the pointer remains BUSY for a *long* time.
- Once the BUSY pointer vanishes, Imagine draws the wireframe appears in
- the perspective window. From that point on, access to all objects in
- the detail editor acts normally.
-
- For example, adding 128 grouped objects in the detail editor (by a
- simple paste operation from a copy of an existing set of 128 grouped
- objects) resulted in a wait of over 5 minutes on a vanilla A3000 with
- 14M. Over 11M remained free. Loading 256 objects resulted in a wait
- of 15 minutes (over 9 M remained free). These were 4 point, 6 edge, 2
- face objects. The wait seems to go up as a high power of object
- complexity. Loading 243 objects only twice as complex took longer
- than 1/2 - 3/4 hours, at which time I gave up and rebooted. Nothing
- else was happening on the machine at the time.
-
- Also, I wrote this code to allow the merging of massive numbers of
- *simple*, nearly identical objects. You know, so I can merge blades
- of grass to make a lawn. Or many individual leaves to make a leafy
- tree. In this case, the above limitation clamps down on one fast. If
- you want to merge only 40 EXTR objects, with a group of a parent and
- two children objects each - fine, write a GXTR chunk to handle this -
- 120 objects is managable, barely. But any more than this and you
- should reconsider what you are trying to do.
-
- Hence, no groups of objects when merging (although you are free to
- change this - just don't break the existing functionality of MXTR)
-
- 2) An addition to process_OBJ(world):
-
- */
-
- /*--------------------------------------------\
- | Charles' magical EXTR object merge hack. |
- \--------------------------------------------*/
- } else if (strcmp(name, "MXTR")==0) {
- p = process_MXTR(create_object(), world);
- if (world->curobj) {
- world->curobj->next = p;
- p->parent = world->curobj->parent;
- } else {
- world->object = p;
- p->parent = 0;
- }
- world->curobj = p;
-
- /*---------------------------------------------------\
- | End of Charles' magical EXTR object merge hack. |
- \---------------------------------------------------*/
-
- } else if (strcmp(name, "DESC")==0) {
- p = create_object();
- if (world->num_DESC > world->num_TOBJ+depth) { /* This is a child */
- depth++; /* Down one in the hierarchy */
- world->curobj->child = p;
- p->parent = world->curobj;
- } else {
- if (world->curobj) {
- world->curobj->next = p;
- p->parent = world->curobj->parent;
- } else {
- world->object = p;
- p->parent = 0;
- }
- }
- world->curobj = p;
- process_DESC(&p->desc, world);
- } else if (strcmp(name, "TOBJ")==0) {
- world->num_TOBJ++;
- if (world->num_TOBJ > world->num_DESC) {
- warn(world->cur_line);
- fprintf(stderr, "TOBJ without DESC. Ignored.\n");
- }
- if (world->num_TOBJ+depth > world->num_DESC) { /* Go back up a level */
- depth--;
- world->curobj=world->curobj->parent;
- }
- } else if (strcmp(name, "END" )==0) {
- if (world->num_DESC > world->num_TOBJ) {
- int i;
- warn(world->cur_line);
- i = world->num_DESC - world->num_TOBJ;
- fprintf(stderr, "Missing %d 'TOBJ'. Inserted.\n", i);
- }
- parse_word(name, 4, 1);
- if (strcmp(name, "OBJ")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END OBJ' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'OBJ Begin' and 'End OBJ' quoted comments do not match\n", world->cur_line);
- break;
- } else if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown OBJ sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
-
- /*---------------------------------------------------------\
- | How to merge EXTR objects into a single mega object. |
- \---------------------------------------------------------*/
- static OBJECT *process_MXTR(obj, world)
- OBJECT *obj;
- WORLD *world;
- { /* process_MXTR */
- register OBJECT *p, *base, *end;
- register DESC *desc, *edesc;
- char this_level[MAXLINE], name[5], nummy[8];
- ULONG pcount, ecount, fcount;
- ULONG pstart, estart, fstart;
- ULONG i;
- XYZ_st *crd, *ocrd;
- ULONG fcnt, ecnt, extrcount;
- FGRP *fgrp, *ofgrp;
-
- pcount = ecount = fcount = 0;
-
- /*---------------------------------------------------------------------\
- | Set up place-holder object - we store all EXTR objects in a linked |
- | list, then merge into obj once we hit END MXTR. |
- \---------------------------------------------------------------------*/
- base = create_object();
-
- base->parent = (struct OBJECT *)0;
- end = base;
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'MXTR'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- /*---------------------------------------------------------------\
- | Get EXTR objects to merge until END MXTR. Any other chuck |
- | ignored. |
- \---------------------------------------------------------------*/
-
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- if (strcmp(name, "EXTR")==0) {
- /*-----------------------------------------------------\
- | Read all EXTR objects that make up this "group". |
- \-----------------------------------------------------*/
- p = process_EXTR(create_object(), world);
- pcount = pcount + p->desc->pcount;
- ecount = ecount + p->desc->ecount;
- fcount = fcount + p->desc->fcount;
- end->next = p;
- p->parent = end;
- end = p;
- } else if (strcmp(name, "END" )==0) {
- /*-------------------------------------\
- | End off this EXTR object series. |
- \-------------------------------------*/
- parse_word(name, 4, 1);
- if (strcmp(name, "MXTR")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END MXTR' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'MXTR Begin' and 'End MXTR' quoted comments do not match\n", world->cur_line);
- break;
- }
- } /* while MXTR */
-
-
- /*-------------------------------------------------\
- | OK, cap base object for our collection scan. |
- \-------------------------------------------------*/
- end->next = (struct OBJECT *)0;
-
- end = base->next; /* Return to first object */
- base->next = (struct OBJECT *)0; /* Since when it comes time to
- free, this is all that will be left */
- edesc = end->desc;
-
- /*----------------------------\
- | Set up our mega object. |
- \----------------------------*/
- if (!(desc = (DESC*)malloc(sizeof(DESC)))) { OUT_MEM("DESC"); }
- bzero((char*)desc, sizeof(DESC));
- obj->desc = desc;
-
- /*-------------------------------------------------------\
- | Copy all attributes from 1st object in EXTR chain. |
- \-------------------------------------------------------*/
- desc_copy(edesc, desc);
-
-
- /*------------------------\
- | Set a few defaults. |
- \------------------------*/
-
- /* Set up defaults: */
- defclst[0] = defclst[1] = defclst[2] = 240; /* TS default */
- defrlst[0] = defrlst[1] = defrlst[2] = 0;
- deftlst[0] = deftlst[1] = deftlst[2] = 0;
- defspc1[0] = defspc1[1] = defspc1[2] = 0;
-
- desc->pcount = pcount;
- desc->ecount = ecount;
-
- /*----------------------------------------------------\
- | Allocate space for point, face, and edge arrays. |
- \----------------------------------------------------*/
- if (!(desc->pnts = (XYZ_st*)malloc(desc->pcount*sizeof(XYZ_st))))
- OUT_MEM("PNTS");
- /* Initialize array */
- for (i=0; i<desc->pcount; i++) {
- desc->pnts[i].x = 0;
- desc->pnts[i].y = 0;
- desc->pnts[i].z = 0;
- }
-
- if (!(desc->edge = (UWORD*)malloc(2*desc->ecount*sizeof(UWORD))))
- OUT_MEM("EDGE");
- /* Initialize array */
- for (i=0; i<2*desc->ecount; i++)
- desc->edge[i] = 0;
-
- malloc_arrays(fcount, desc);
-
- /*---------------------------------------------------------\
- | Now walk down objects, copying point, face, edge, |
- | color, transparancy, and reflectivity information. |
- | All other attributes have been stolen from the first |
- | object. Subobjects are copied |
- | POTENTIAL BUG: I AM ASSUMING THE EXTR OBJECTS WE READ |
- | HERE ARE NOT THEMSELVES HIERACHIES. MIGHT NEED SOME |
- | RECURSION, OR SOMETHING SIMILAR, IF THIS IS THE CASE. |
- \---------------------------------------------------------*/
- ocrd = desc->pnts;
-
- pstart = estart = fstart = 0;
- fcnt = ecnt = extrcount = 0;
-
- while (end != (struct OBJECT *)0)
- { /* For all objects to merge */
- edesc = end->desc;
- /*---------------------------------------------------------------\
- | Copy points over - OK, I could use BCOPY, but I want control. |
- \---------------------------------------------------------------*/
- crd = edesc->pnts;
- for (i = 0; i < edesc->pcount; i++)
- {
- ocrd->x = crd->x;
- ocrd->y = crd->y;
- ocrd->z = crd->z;
- ocrd++;
- crd++;
- }
-
- /*---------------\
- | Now edges. |
- \---------------*/
-
- for (i=0; i<2*edesc->ecount; i++)
- {
- desc->edge[ecnt] = edesc->edge[i] + pstart;
- ecnt++;
- }
-
- /*----------------------------------------------\
- | And the faces and their basic attributes. |
- \----------------------------------------------*/
- for (i = 0; i<3*edesc->fcount; i+=3)
- {
- desc->face[fcnt] = edesc->face[i] + estart;
- desc->face[fcnt+1] = edesc->face[i+1] + estart;
- desc->face[fcnt+2] = edesc->face[i+2] + estart;
- desc->clst[fcnt] = edesc->clst[i];
- desc->clst[fcnt+1] = edesc->clst[i+1];
- desc->clst[fcnt+2] = edesc->clst[i+2];
- desc->rlst[fcnt] = edesc->rlst[i];
- desc->rlst[fcnt+1] = edesc->rlst[i+1];
- desc->rlst[fcnt+2] = edesc->rlst[i+2];
- desc->tlst[fcnt] = edesc->tlst[i];
- desc->tlst[fcnt+1] = edesc->tlst[i+1];
- desc->tlst[fcnt+2] = edesc->tlst[i+2];
- fcnt+=3;
- }
-
- /*----------------------------------\
- | And the subgroup definitions. |
- \----------------------------------*/
- if (edesc->fgrp)
- { /* Do subgroups */
- fgrp = edesc->fgrp;
- while (fgrp != (FGRP *) 0)
- { /* While subgroups to copy */
- /*------------------------\
- | Get FGRP structure. |
- \------------------------*/
- if (!(ofgrp = (FGRP*)malloc(sizeof(FGRP))))
- OUT_MEM("FGRP");
- /*------------------------------\
- | Fill out name and number. |
- \------------------------------*/
- bzero((char *)ofgrp, sizeof(FGRP));
-
- ofgrp->num = fgrp->num;
-
- /*-----------------------------------------------\
- | Mangle name so unique for each subobject of |
- | each component EXTR object. |
- \-----------------------------------------------*/
- i = strlen(fgrp->name);
- if (i > 13) /* The name field is 18 characters */
- i = 13; /* tops, and we remove 5 characters for
- the ASCII representations of 0-65535 */
- strncpy(ofgrp->name, fgrp->name, i);
- ofgrp->name[i] = '\0'; /* Arrays start at 0 */
- sprintf(nummy, "%d", extrcount);
- strcat(ofgrp->name, nummy); /* uniquely tag subgroup
- name by number of parent
- EXTR object */
-
- /*-----------------------------\
- | Insert into linked list. |
- \-----------------------------*/
- ofgrp->next = desc->fgrp;
- desc->fgrp = ofgrp;
-
- /*-----------------------------------\
- | And copy in the face indicies. |
- \-----------------------------------*/
- if (!(ofgrp->face =
- (UWORD *)malloc((fgrp->num)*sizeof(UWORD))))
- OUT_MEM("FGRP");
- for (i = 0; i < fgrp->num; i++)
- {
- ofgrp->face[i] = (UWORD) (fgrp->face[i] + fstart);
- }
-
- fgrp = fgrp->next;
- } /* While subgroups to copy */
- } /* Do subgroups */
-
- /*-------------------------------------------------------\
- | Copying textures in a similar manner would be |
- | rather difficult, since we can only have 4 textures |
- | per object. I suggest having the user make their |
- | own subgroups and apply the texture to the merged |
- | object, since we run into too many difficulties if |
- | we try to do this for them here. There is a time |
- | and a place for everything, and I think textures |
- | don't belong here. |
- \-------------------------------------------------------*/
-
- /*----------------------------\
- | Set up for next object. |
- \----------------------------*/
- pstart = pstart + edesc->pcount;
- estart = estart + edesc->ecount;
- fstart = fstart + edesc->fcount;
- extrcount++;
- p = end;
- end = end->next;
-
- /*--------------------------------------------------\
- | And free object now that we are done with it. |
- \--------------------------------------------------*/
- p->next = (struct OBJECT *)0; /* Delete only this guy in chain */
- p->parent = (struct OBJECT *)0;
- free_object(p);
- } /* For all objects to merge */
-
- /*---------------------\
- | Free base object. |
- \---------------------*/
- free_object(base);
-
- /*-------------------------\
- | And return in glory. |
- \-------------------------*/
- return(obj);
-
- } /* process_MXTR */
-
- /*-------------------------------------------------------------------\
- | Copy an object's attributes from one desc structure to another. |
- | What a pain. But someone had to do it... |
- \-------------------------------------------------------------------*/
- static void desc_copy(edesc, desc)
- DESC *edesc, /* input desc structure */
- *desc; /* output desc structure */
- { /* desc_copy */
- if (edesc->name != '\0')
- strcpy(desc->name, edesc->name);
-
- if (edesc->eflg)
- {
- if (!(desc->eflg = (EFLG*)malloc(sizeof(EFLG))))
- OUT_MEM("EFLG");
- bcopy((char *)edesc->eflg, (char *)desc->eflg, sizeof(EFLG));
- if (edesc->eflg->eflg)
- {
- if (!(desc->eflg->eflg =
- (UBYTE*)malloc(desc->eflg->num*sizeof(UBYTE))))
- OUT_MEM("EFLG");
- bcopy((char *)edesc->eflg->eflg, (char *)edesc->eflg->eflg,
- edesc->eflg->num*sizeof(UBYTE));
- }
- }
-
- if (edesc->shap)
- {
- if (!(desc->shap=(WORD*)malloc(2*sizeof(WORD))))
- { OUT_MEM("SHAP"); }
- bcopy((char *)edesc->shap, (char *)desc->shap, 2*sizeof(WORD));
- }
-
- if (edesc->posi)
- {
- if (!(desc->posi=(XYZ_st*)malloc(sizeof(XYZ_st))))
- { OUT_MEM("POSI"); }
- bcopy((char *)edesc->posi, (char *)desc->posi, sizeof(XYZ_st));
- }
-
- if (edesc->axis)
- {
- if (!(desc->axis=(AXIS*)malloc(sizeof(AXIS))))
- { OUT_MEM("AXIS"); }
- bcopy((char *)edesc->axis, (char *)desc->axis, sizeof(AXIS));
- }
-
- if (edesc->size)
- {
- if (!(desc->size=(XYZ_st*)malloc(sizeof(XYZ_st))))
- { OUT_MEM("SIZE"); }
- bcopy((char *)edesc->size, (char *)desc->size, sizeof(XYZ_st));
- }
-
- if (edesc->colr)
- {
- if (!(desc->colr = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("COLR"); }
- bcopy((char *)edesc->colr, (char *)desc->colr, sizeof(RGB_st));
- }
-
- if (edesc->refl)
- {
- if (!(desc->refl = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("REFL"); }
- bcopy((char *)edesc->refl, (char *)desc->refl, sizeof(RGB_st));
- }
-
- if (edesc->tran)
- {
- if (!(desc->tran = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("TRAN"); }
- bcopy((char *)edesc->tran, (char *)desc->tran, sizeof(RGB_st));
- }
-
- if (edesc->spc1)
- {
- if (!(desc->spc1 = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("SPC1"); }
- bcopy((char *)edesc->spc1, (char *)desc->spc1, sizeof(RGB_st));
- }
-
- if (edesc->tpar)
- {
- if (!(desc->tpar=(double*)malloc(16*sizeof(double))))
- { OUT_MEM("TPAR"); }
- bcopy((char *)edesc->tpar, (char *)desc->tpar, 16*sizeof(double));
- }
-
- if (edesc->surf)
- {
- if (!(desc->surf=(UBYTE*)malloc(5*sizeof(UBYTE))))
- { OUT_MEM("SURF"); }
- bcopy((char*)edesc->surf, (char *)desc->surf, 5*sizeof(UBYTE));
- }
-
- if (edesc->mttr)
- {
- if (!(desc->mttr=(MTTR*)malloc(sizeof(MTTR))))
- { OUT_MEM("MTTR"); }
- bcopy((char*)edesc->mttr, (char *)desc->mttr, sizeof(MTTR));
- }
-
- if (edesc->spec)
- {
- if (!(desc->spec=(UBYTE*)malloc(2*sizeof(UBYTE))))
- { OUT_MEM("SPEC"); }
- bcopy((char*)edesc->spec, (char *)desc->spec, 2*sizeof(UBYTE));
- }
-
- if (edesc->prp0)
- {
- if (!(desc->prp0=(UBYTE*)malloc(6*sizeof(UBYTE))))
- { OUT_MEM("PRP0"); }
- bcopy((char*)edesc->prp0, (char *)desc->prp0, 6*sizeof(UBYTE));
- }
-
- if (edesc->prp1)
- {
- if (!(desc->prp1=(UBYTE*)malloc(8*sizeof(UBYTE))))
- { OUT_MEM("PRP1"); }
- bcopy((char*)edesc->prp1, (char *)desc->prp1, 8*sizeof(UBYTE));
- }
-
- if (edesc->ints)
- {
- if (!(desc->ints=(double*)malloc(sizeof(double))))
- { OUT_MEM("INTS"); }
- bcopy((char *)edesc->ints, (char *)desc->ints, sizeof(double));
- }
-
- if (edesc->int1)
- {
- if (!(desc->int1=(XYZ_st*)malloc(sizeof(XYZ_st))))
- { OUT_MEM("INT1"); }
- bcopy((char *)edesc->int1, (char *)desc->int1, sizeof(XYZ_st));
- }
- } /* desc_copy */
- /*----------------------\
- | That's all folks. |
- \----------------------*/
-
- static OBJECT *process_EXTR(obj, world)
- OBJECT *obj;
- WORLD *world;
- {
- register EXTR *extr;
- register OBJECT *p;
- char this_level[MAXLINE], name[5];
- MTRX *mtrx;
- WORLD *new;
- FILE *newinp;
-
- if (!(extr = obj->extr = (EXTR*)malloc(sizeof(EXTR)))) { OUT_MEM("EXTR"); }
- bzero((char*)extr, sizeof(EXTR));
- mtrx = &extr->mtrx;
- /* Initialize structure */
- mtrx->tran.x = mtrx->tran.y = mtrx->tran.z = 0.0;
- mtrx->scal.x = mtrx->scal.y = mtrx->scal.z = 1.0;
- mtrx->rota1.y = mtrx->rota1.z = 0.0;
- mtrx->rota2.x = mtrx->rota2.z = 0.0;
- mtrx->rota3.x = mtrx->rota3.y = 0.0;
- mtrx->rota1.x = mtrx->rota2.y = mtrx->rota3.z = 1.0;
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'EXTR'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- if (strcmp(name, "MTRX")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "TRAN")==0) stuff_XYZ(&mtrx->tran);
- else if (strcmp(name, "SCAL")==0) stuff_XYZ(&mtrx->scal);
- else if (strcmp(name, "ROTA")==0) {
- stuff_XYZ(&mtrx->rota1);
- stuff_XYZ(&mtrx->rota2);
- stuff_XYZ(&mtrx->rota3);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown MTRX field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else if (strcmp(name, "LOAD")==0) {
- parse_word(extr->filename, 80, 0);
- } else if (strcmp(name, "END" )==0) {
- parse_word(name, 4, 1);
- if (strcmp(name, "EXTR")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END EXTR' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'EXTR Begin' and 'End EXTR' quoted comments do not match\n", world->cur_line);
- break;
- } else if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown EXTR sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- /* Now, load in the external object */
- if (!(newinp=fopen(extr->filename, "r"))) {
- fprintf(stderr, "Can't load in EXTR object: '%s'... ignored.\n",
- extr->filename);
- return(obj);
- }
- new = read_World(newinp);
- fclose(newinp);
- /* scale, rotate, and translate new object hierarchy */
- for (p=new->object; p; p=p->next)
- move_extr(p, mtrx);
- /* Free up unused memory */
- free((char*)obj->extr);
- free((char*)obj);
- obj = new->object;
- free((char*)new);
- return(obj);
- }
-
- void move_extr(obj, mtrx)
- register OBJECT *obj;
- register MTRX *mtrx;
- {
- register XYZ_st *p;
- register int i;
- register double x, y, z;
- if (obj->desc) {
- if (obj->desc->posi) {
- obj->desc->posi->x += mtrx->tran.x;
- obj->desc->posi->y += mtrx->tran.y;
- obj->desc->posi->z += mtrx->tran.z;
- }
- for (p=obj->desc->pnts,i=obj->desc->pcount; i--; p++) {
- x = (p->x*mtrx->scal.x);
- y = (p->y*mtrx->scal.y);
- z = (p->z*mtrx->scal.z);
- p->x = x*mtrx->rota1.x +
- y*mtrx->rota1.y +
- z*mtrx->rota1.z +
- mtrx->tran.x;
- p->y = x*mtrx->rota2.x +
- y*mtrx->rota2.y +
- z*mtrx->rota2.z +
- mtrx->tran.y;
- p->z = x*mtrx->rota3.x +
- y*mtrx->rota3.y +
- z*mtrx->rota3.z +
- mtrx->tran.z;
- }
- if (obj->desc->size) {
- obj->desc->size->x = mtrx->scal.x;
- obj->desc->size->y = mtrx->scal.y;
- obj->desc->size->z = mtrx->scal.z;
- }
- }
- for (obj=obj->child; obj; obj=obj->next)
- move_extr(obj, mtrx); /* Process all children */
- }
-
- void OUT_MEM(s)
- char *s;
- {
- if (s)
- fprintf(stderr, "Ran out of memory while processing '%s'. Sorry.\n", s);
- exit(-1);
- }
-
- static void malloc_arrays(i, desc)
- register int i;
- register DESC *desc;
- {
- if (!desc->fcount) {
- desc->fcount = i;
- if (!(desc->face=(UWORD*)malloc(3*desc->fcount*sizeof(UWORD))))OUT_MEM((char*)0);
- if (!(desc->clst=(UBYTE*)malloc(3*desc->fcount*sizeof(UBYTE))))OUT_MEM((char*)0);
- if (!(desc->rlst=(UBYTE*)malloc(3*desc->fcount*sizeof(UBYTE))))OUT_MEM((char*)0);
- if (!(desc->tlst=(UBYTE*)malloc(3*desc->fcount*sizeof(UBYTE))))OUT_MEM((char*)0);
- /* Initialize arrays */
- for (i=0; i<3*desc->fcount; i+=3) {
- desc->face[i] = desc->face[i+1] = desc->face[i+2] = 0;
- desc->clst[i] = defclst[0];
- desc->clst[i+1] = defclst[1];
- desc->clst[i+2] = defclst[2];
- desc->rlst[i] = defrlst[0];
- desc->rlst[i+1] = defrlst[1];
- desc->rlst[i+2] = defrlst[2];
- desc->tlst[i] = deftlst[0];
- desc->tlst[i+1] = deftlst[1];
- desc->tlst[i+2] = deftlst[2];
- }
- } else if (i != desc->fcount) {
- fprintf(stderr, "ERROR: FACE and [C|R|T]LST 'Count' values inconsistant.\n");
- OUT_MEM((char*)0);
- }
- }
-
- static void process_DESC(orig, world)
- DESC **orig;
- WORLD *world;
- {
- register DESC *desc;
- register int i, j;
- char this_level[MAXLINE], name[5];
- FGRP *fgrp;
-
- if (!(desc = *orig = (DESC*)malloc(sizeof(DESC)))) { OUT_MEM("DESC"); }
- bzero((char*)desc, sizeof(DESC));
-
- /* Set up defaults: */
- defclst[0] = defclst[1] = defclst[2] = 240; /* TS default */
- defrlst[0] = defrlst[1] = defrlst[2] = 0;
- deftlst[0] = deftlst[1] = deftlst[2] = 0;
- defspc1[0] = defspc1[1] = defspc1[2] = 0;
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'DESC'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- world->num_DESC++;
-
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- /* Put most-frequent commands near the front of this list */
- if (strcmp(name, "PNTS")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "POIN")==0) {
- if (!desc->pcount) {
- fprintf(stderr, "ERROR: Line %d: 'PNTS Point' encountered before 'PNTS PCount'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->pcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: PNTS Point[%d] should be [0..%d]\n", world->cur_line, i, desc->pcount-1);
- continue;
- }
- stuff_XYZ(&desc->pnts[i]);
- } else if (strcmp(name, "PCOU")==0) {
- if (!desc->pcount) {
- desc->pcount = get_UWORD();
- if (!(desc->pnts = (XYZ_st*)malloc(desc->pcount*sizeof(XYZ_st))))
- OUT_MEM("PNTS");
- /* Initialize array */
- for (i=0; i<desc->pcount; i++) {
- desc->pnts[i].x = 0;
- desc->pnts[i].y = 0;
- desc->pnts[i].z = 0;
- }
- } else {
- fprintf(stderr, "WARNING: Line %d: PNTS Pcount defined more than once.\n", world->cur_line);
- }
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown PNTS field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "EDGE")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "EDGE")==0) {
- if (!desc->ecount) {
- fprintf(stderr, "ERROR: Line %d: 'EDGE Edge' encountered before 'EDGE ECount'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->ecount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: EDGE Edge[%d] should be [0..%d]\n", world->cur_line, i, desc->ecount-1);
- continue;
- }
- desc->edge[2*i] = get_UWORD();
- desc->edge[2*i+1] = get_UWORD();
- } else if (strcmp(name, "ECOU")==0) {
- if (!desc->ecount) {
- desc->ecount = get_UWORD();
- if (!(desc->edge = (UWORD*)malloc(2*desc->ecount*sizeof(UWORD))))
- OUT_MEM("EDGE");
- /* Initialize array */
- for (i=0; i<2*desc->ecount; i++)
- desc->edge[i] = 0;
- } else {
- fprintf(stderr, "WARNING: Line %d: EDGE Ecount defined more than once.\n", world->cur_line);
- }
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown EDGE field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "EFLG")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "COUN")==0) {
- if (!desc->eflg) {
- if (!(desc->eflg = (EFLG*)malloc(sizeof(EFLG))))
- OUT_MEM("EFLG");
- desc->eflg->num = get_UWORD();
- if (!(desc->eflg->eflg = (UBYTE*)malloc(desc->eflg->num*sizeof(UBYTE))))
- OUT_MEM("EFLG");
- /* Initialize array */
- for (i=0; i<desc->eflg->num; i++)
- desc->eflg->eflg[i] = 0;
- } else {
- fprintf(stderr, "WARNING: Line %d: EFLG Count defined more than once.\n", world->cur_line);
- }
- } else if (strcmp(name, "EFLG")==0) {
- if (!desc->eflg) {
- fprintf(stderr, "ERROR: Line %d: 'EFLG Eflg' encountered before 'EFLG Count'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->eflg->num) {
- fprintf(stderr, "WARNING: Line %d: Bad index: EFLG Eflg[%d] should be [0..%d]\n", world->cur_line, i, desc->eflg->num-1);
- continue;
- }
- desc->eflg->eflg[i] = get_UWORD();
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown EFLG field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "FACE")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "CONN")==0) {
- if (!desc->fcount) {
- fprintf(stderr, "ERROR: Line %d: 'FACE Connects' encountered before 'FACE TCount'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->fcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: FACE Connects[%d] should be [0..%d]\n", world->cur_line, i, desc->fcount-1);
- continue;
- }
- desc->face[3*i] = get_UWORD();
- desc->face[3*i+1] = get_UWORD();
- desc->face[3*i+2] = get_UWORD();
- } else if (strcmp(name, "TCOU")==0) {
- i = get_UWORD();
- malloc_arrays(i, desc);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown FACE field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "FGRP")==0) {
- parse_word(name, 4, 1);
- if (strcmp(name, "NAME")==0) {
- if (!(fgrp = (FGRP*)malloc(sizeof(FGRP))))
- OUT_MEM("FGRP");
- bzero((char*)fgrp, sizeof(FGRP));
- parse_word(ps, 0, 0);
- strncpy(fgrp->name, ps, 18);
- fgrp->name[18]='\0';
- fgrp->next = desc->fgrp;
- desc->fgrp = fgrp;
- } else if (strcmp(name, "COUN")==0) {
- i = get_UWORD();
- if (!desc->fgrp) {
- fprintf(stderr, "ERROR: Line %d: 'FGRP Count' encountered before 'FGRP Name'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- if (desc->fgrp->face) {
- fprintf(stderr, "ERROR: Line %d: 'FGRP Count' encountered twice\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- desc->fgrp->num = i;
- if (!(desc->fgrp->face = (UWORD*)malloc(i*sizeof(UWORD))))
- OUT_MEM("FGRP");
- while (i--) desc->fgrp->face[i] = 0;
- } else if (strcmp(name, "FACE")==0) {
- i = get_UWORD();
- if (i<0 || i>=desc->fgrp->num) {
- fprintf(stderr, "WARNING: Line %d: Bad index: FGRP Face[%d] should be [0..%d]\n", world->cur_line, i, desc->fgrp->num-1);
- continue;
- }
- desc->fgrp->face[i] = get_UWORD();
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown FGRP field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "CLST")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "COLO")==0) {
- if (!desc->fcount) {
- fprintf(stderr, "ERROR: Line %d: 'CLST Color' encountered before 'CLST Count'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->fcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: CLST Color[%d] should be [0..%d]\n", world->cur_line, i, desc->fcount-1);
- continue;
- }
- stuff_RGB((RGB_st*)&desc->clst[3*i]); /* Place 3 UBYTE's into array */
- } else if (strcmp(name, "COUN")==0) {
- i = get_UWORD();
- malloc_arrays(i, desc);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown CLST field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "RLST")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "COLO")==0) {
- if (!desc->fcount) {
- fprintf(stderr, "ERROR: Line %d: 'RLST Color' encountered before 'RLST Count'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->fcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: RLST Color[%d] should be [0..%d]\n", world->cur_line, i, desc->fcount-1);
- continue;
- }
- stuff_RGB((RGB_st*)&desc->rlst[3*i]); /* Place three UBYTE's into array */
- } else if (strcmp(name, "COUN")==0) {
- i = get_UWORD();
- malloc_arrays(i, desc);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown RLST field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "TLST")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "COLO")==0) {
- if (!desc->fcount) {
- fprintf(stderr, "ERROR: Line %d: 'TLST Color' encountered before 'TLST Count'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->fcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: TLST Color[%d] should be [0..%d]\n", world->cur_line, i, desc->fcount-1);
- continue;
- }
- stuff_RGB((RGB_st*)&desc->tlst[3*i]); /* Place three UBYTE's into array */
- } else if (strcmp(name, "COUN")==0) {
- i = get_UWORD();
- malloc_arrays(i, desc);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown TLST field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "NAME")==0) {
- parse_word(ps, 0, 0);
- strncpy(desc->name, ps, 18);
- desc->name[18]='\0';
- } else
- if (strcmp(name, "SHAP")==0) {
- if (!desc->shap) {
- if (!(desc->shap=(WORD*)malloc(2*sizeof(WORD))))
- { OUT_MEM("SHAP"); }
- desc->shap[0] = 2; /* TS defaults */
- desc->shap[1] = 0;
- }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "SHAP")==0) desc->shap[0] = get_UWORD();
- else if (strcmp(name, "LAMP")==0) desc->shap[1] = get_UWORD();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown SHAP field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "POSI")==0) {
- if (!desc->posi) {
- if (!(desc->posi=(XYZ_st*)malloc(sizeof(XYZ_st))))
- { OUT_MEM("POSI"); }
- }
- stuff_XYZ(desc->posi);
- } else
- if (strcmp(name, "AXIS")==0) {
- if (!desc->axis) {
- if (!(desc->axis=(AXIS*)malloc(sizeof(AXIS))))
- { OUT_MEM("AXIS"); }
- bzero((char*)desc->axis, sizeof(AXIS));
- desc->axis->xaxi.x = 1;
- desc->axis->yaxi.y = 1;
- desc->axis->zaxi.z = 1;
- }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "XAXI")==0) stuff_XYZ(&desc->axis->xaxi);
- else if (strcmp(name, "YAXI")==0) stuff_XYZ(&desc->axis->yaxi);
- else if (strcmp(name, "ZAXI")==0) stuff_XYZ(&desc->axis->zaxi);
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown AXIS field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "SIZE")==0) {
- if (!desc->size) {
- if (!(desc->size=(XYZ_st*)malloc(sizeof(XYZ_st))))
- { OUT_MEM("SIZE"); }
- }
- stuff_XYZ(desc->size);
- } else
- if (strcmp(name, "COLR")==0) {
- if (!desc->colr) {
- if (!(desc->colr = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("COLR"); }
- }
- stuff_RGB((RGB_st*)&defclst[0]);
- desc->colr->r = defclst[0];
- desc->colr->g = defclst[1];
- desc->colr->b = defclst[2];
- #ifdef DO_I_REALLY_WANT_TO_DO_THIS
- if (desc->fcount) { /* Already initialized... rewrite */
- for (i=3*desc->fcount; i; ) { /* Reverse - efficiency */
- desc->clst[--i] = defclst[2];
- desc->clst[--i] = defclst[1];
- desc->clst[--i] = defclst[0];
- }
- }
- #endif
- } else
- if (strcmp(name, "REFL")==0) {
- if (!desc->refl) {
- if (!(desc->refl = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("REFL"); }
- }
- stuff_RGB((RGB_st*)&defrlst[0]);
- desc->refl->r = defrlst[0];
- desc->refl->g = defrlst[1];
- desc->refl->b = defrlst[2];
- #ifdef DO_I_REALLY_WANT_TO_DO_THIS
- if (desc->fcount) { /* Already initialized... rewrite */
- for (i=3*desc->fcount; i; ) { /* Reverse - efficiency */
- desc->rlst[--i] = defrlst[2];
- desc->rlst[--i] = defrlst[1];
- desc->rlst[--i] = defrlst[0];
- }
- }
- #endif
- } else
- if (strcmp(name, "TRAN")==0) {
- if (!desc->tran) {
- if (!(desc->tran = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("TRAN"); }
- }
- stuff_RGB((RGB_st*)&deftlst[0]);
- desc->tran->r = deftlst[0];
- desc->tran->g = deftlst[1];
- desc->tran->b = deftlst[2];
- #ifdef DO_I_REALLY_WANT_TO_DO_THIS
- if (desc->fcount) { /* Already initialized... rewrite */
- for (i=3*desc->fcount; i; ) { /* Reverse - efficiency */
- desc->tlst[--i] = deftlst[2];
- desc->tlst[--i] = deftlst[1];
- desc->tlst[--i] = deftlst[0];
- }
- }
- #endif
- } else
- if (strcmp(name, "SPC1")==0) {
- if (!desc->spc1) {
- if (!(desc->spc1 = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("SPC1"); }
- }
- stuff_RGB((RGB_st*)&defspc1[0]);
- desc->spc1->r = defspc1[0];
- desc->spc1->g = defspc1[1];
- desc->spc1->b = defspc1[2];
- } else
- if (strcmp(name, "TPAR")==0) {
- if (!desc->tpar) {
- if (!(desc->tpar=(double*)malloc(16*sizeof(double))))
- { OUT_MEM("TPAR"); }
- bzero((char*)desc->tpar, 16*sizeof(double));
- }
- i = get_UWORD();
- if (i<0 || i>15) {
- fprintf(stderr, "WARNING: Line %d: Bad index: TPAR[%d] should be [0..15]\n", world->cur_line, i);
- continue;
- }
- desc->tpar[i] = get_FRACT();
- } else
- if (strcmp(name, "SURF")==0) {
- if (!desc->surf) {
- if (!(desc->surf=(UBYTE*)malloc(5*sizeof(UBYTE))))
- { OUT_MEM("SURF"); }
- bzero((char*)desc->surf, 5*sizeof(UBYTE));
- }
- i = get_UWORD();
- if (i<0 || i>4) {
- fprintf(stderr, "WARNING: Line %d: Bad index: SURF[%d] should be [0..4]\n", world->cur_line, i);
- continue;
- }
- desc->surf[i] = get_UBYTE();
- } else
- if (strcmp(name, "MTTR")==0) {
- if (!desc->mttr) {
- if (!(desc->mttr=(MTTR*)malloc(sizeof(MTTR))))
- { OUT_MEM("MTTR"); }
- bzero((char*)desc->mttr, sizeof(MTTR));
- }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "TYPE")==0) {
- desc->mttr->type = get_UBYTE();
- if (desc->mttr->type>4) {
- fprintf(stderr, "WARNING: Line %d: Invalid MTTR refraction Type %d. Must be [0..4]\n", world->cur_line, desc->mttr->type);
- desc->mttr->type = 0;
- continue;
- }
- } else if (strcmp(name, "INDE")==0) { /* Must be between 1.0 and 3.55 inclusive */
- desc->mttr->indx = get_FRACT();
- if (desc->mttr->indx<1.0 || desc->mttr->indx>3.55) {
- fprintf(stderr, "WARNING: Line %d: Invalid MTTR Index of refraction. Must be (1.0 - 3.55)\n", world->cur_line);
- desc->mttr->indx = 1.0;
- continue;
- }
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown MTTR field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "SPEC")==0) {
- if (!desc->spec) {
- if (!(desc->spec=(UBYTE*)malloc(2*sizeof(UBYTE))))
- { OUT_MEM("SPEC"); }
- bzero((char*)desc->spec, 2*sizeof(UBYTE));
- }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "SPEC")==0) desc->spec[0] = get_UBYTE();
- else if (strcmp(name, "HARD")==0) desc->spec[1] = get_UBYTE();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown SPEC field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "PRP0")==0) {
- if (!desc->prp0) {
- if (!(desc->prp0=(UBYTE*)malloc(6*sizeof(UBYTE))))
- { OUT_MEM("PRP0"); }
- bzero((char*)desc->prp0, 6*sizeof(UBYTE));
- desc->prp0[0] = 255; /* TS defaults */
- desc->prp0[3] = 1;
- }
- i = get_UWORD();
- if (i<0 || i>5) {
- fprintf(stderr, "WARNING: Line %d: Bad index: PRP0[%d] should be [0..5]\n", world->cur_line, i);
- continue;
- }
- desc->prp0[i] = get_UBYTE();
- } else
- if (strcmp(name, "PRP1")==0) {
- if (!desc->prp1) {
- if (!(desc->prp1=(UBYTE*)malloc(8*sizeof(UBYTE))))
- { OUT_MEM("PRP1"); }
- bzero((char*)desc->prp1, 8*sizeof(UBYTE));
- }
- i = get_UWORD();
- if (i<0 || i>7) {
- fprintf(stderr, "WARNING: Line %d: Bad index: PRP1[%d] should be [0..7]\n", world->cur_line, i);
- continue;
- }
- desc->prp1[i] = get_UBYTE();
- } else
- if (strcmp(name, "TXT2")==0) {
- i = get_UWORD();
- if (i<0 || i>3) {
- fprintf(stderr, "WARNING: Line %d: TXT2 index must be [0..3].\n",
- world->cur_line);
- i=3;
- }
- if (!desc->txt2[i])
- if (!(desc->txt2[i] = (TXT2*)malloc(sizeof(TXT2))))
- OUT_MEM("TXT2");
- parse_word(name, 4, 1); /* get field */
- if (strcmp(name, "FLAG") == 0)
- desc->txt2[i]->Flags = get_UWORD();
- else if (strcmp(name, "TRAN") == 0)
- stuff_XYZ(&desc->txt2[i]->TAxis.tran);
- else if (strcmp(name, "XAXI") == 0)
- stuff_XYZ(&desc->txt2[i]->TAxis.rota1);
- else if (strcmp(name, "YAXI") == 0)
- stuff_XYZ(&desc->txt2[i]->TAxis.rota2);
- else if (strcmp(name, "ZAXI") == 0)
- stuff_XYZ(&desc->txt2[i]->TAxis.rota3);
- else if (strcmp(name, "SCAL") == 0)
- stuff_XYZ(&desc->txt2[i]->TAxis.scal);
- else if (strcmp(name, "PARA") == 0) {
- j = get_UWORD();
- desc->txt2[i]->Params[j] = get_FRACT();
- } else if (strcmp(name, "PFLA") == 0) {
- j = get_UWORD();
- desc->txt2[i]->PFlags[j] = get_UWORD();
- } else if (strcmp(name, "SUBG") == 0) {
- parse_word(ps, 0, 0);
- strncpy(desc->txt2[i]->SubName, ps, 18);
- desc->txt2[i]->SubName[18]='\0';
- } else if (strcmp(name, "TEXT") == 0)
- parse_word(desc->txt2[i]->Name,0,0);
- else {
- #ifdef WARNING
- fprintf(stderr, "WARNING: Line %d: Unknown TXT2 field: '%s'\n",
- world->cur_line, name);
- #endif
- continue;
- }
- } else
- if (strcmp(name, "INTS")==0) {
- if (!desc->ints) {
- if (!(desc->ints=(double*)malloc(sizeof(double))))
- { OUT_MEM("INTS"); }
- }
- *desc->ints = get_FRACT();
- } else
- if (strcmp(name, "INT1")==0) {
- if (!desc->int1) desc->int1=(XYZ_st*)malloc(sizeof(XYZ_st));
- if (!desc->int1) { OUT_MEM("INT1"); }
- stuff_XYZ(desc->int1);
- } else
- if (strcmp(name, "STRY")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "PATH")==0) parse_word(desc->stry->path,18,0);
- else if (strcmp(name, "TRAN")==0) stuff_XYZ(&desc->stry->tran);
- else if (strcmp(name, "ROTA")==0) stuff_XYZ(&desc->stry->rota);
- else if (strcmp(name, "SCAL")==0) stuff_XYZ(&desc->stry->scal);
- else
- if (strcmp(name, "INFO")==0) {
- desc->stry->info = 0;
- while (strin[0]) {
- parse_word(ps, 7, 1);
- if (strcmp(ps, "ABS_TRA")==0) desc->stry->info|=(1<<0);
- else if (strcmp(ps, "ABS_ROT")==0) desc->stry->info|=(1<<1);
- else if (strcmp(ps, "ABS_SCL")==0) desc->stry->info|=(1<<2);
- else if (strcmp(ps, "LOC_TRA")==0) desc->stry->info|=(1<<4);
- else if (strcmp(ps, "LOC_ROT")==0) desc->stry->info|=(1<<5);
- else if (strcmp(ps, "LOC_SCL")==0) desc->stry->info|=(1<<6);
- else if (strcmp(ps, "X_ALIGN")==0) desc->stry->info|=(1<<8);
- else if (strcmp(ps, "Y_ALIGN")==0) desc->stry->info|=(1<<9);
- else if (strcmp(ps, "Z_ALIGN")==0) desc->stry->info|=(1<<10);
- else if (strcmp(ps, "FOLLOW_")==0) desc->stry->info|=(1<<12);
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown STRY INFO flag: '%s'\n",
- world->cur_line, ps);
- continue;
- }
- }
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown STRY field: '%s'\n",
- world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "END")==0) {
- parse_word(name, 4, 1);
- if (strcmp(name, "DESC")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END DESC' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'DESC Begin' and 'End DESC' quoted comments do not match\n", world->cur_line);
- break;
- } else if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown DESC sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
-
- /**************************************************************************/
-
- /* readTistg.c - read a Textual Imagine Stage file
- * - written by Glenn M. Lewis - 8/11/92
- * - Imagine3 update by Rob Hounsell - Sept 94
- */
-
- static void process_OSZ2();
- static void process_OSIZ();
- static void process_POS2();
- static void process_POSN();
- static void process_ALN2();
- static void process_ALGN();
- static void process_PALN();
- static void process_TALN();
- static void process_ASSC();
- static void process_HING();
- static void process_LYR0();
- static void process_PTH2();
- static void process_GLB3();
- static void process_GLB2();
- static void process_AXIS();
- static void process_LIT2();
- static void process_LITE();
- static void process_FIL3();
- static void process_FILE();
- static void process_SPFX();
- static void process_SOBJ();
-
- static void process_ISTG(world)
- WORLD *world;
- {
- char name[5];
- char this_level[MAXLINE];
-
- if (world->istg) {
- fprintf(stderr, "Parse error: More than one ISTG chunk!\n"); exit(-1); }
- /* Allocate the ISTG structure */
- if (!(world->istg = (ISTG*)malloc(sizeof(ISTG)))) { OUT_MEM("ISTG"); }
- bzero((char*)world->istg, sizeof(ISTG));
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'ISTG'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- if (strcmp(name, "MAXF")==0) {
- world->istg->maxf = get_UWORD();
- } else
- if (strcmp(name, "LOOP")==0) {
- world->istg->loop = get_UWORD();
- } else
- if (strcmp(name, "SOBJ")==0) { process_SOBJ(world);
- } else if (strcmp(name, "END")==0) {
- parse_word(name, 4, 1);
- if (strcmp(name, "ISTG")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END ISTG' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'ISTG Begin' and 'End ISTG' quoted comments do not match\n", world->cur_line);
- break;
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown ISTG sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- continue;
- }
- }
- /* All done. */
- }
-
- extern SOBJ *add_SOBJ(); /* to tail of ISTG's SOBJ list */
-
- static void process_SOBJ(world)
- WORLD *world;
- {
- char this_level[MAXLINE], name[5];
- SOBJ *sobj;
-
- if (verbose_flag>1) fprintf(stderr, "SOBJ chunk.\n");
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'SOBJ'\n",
- world->cur_line);
- }
- /* Add another SOBJ to the current ISTG list */
- parse_word(this_level, 0, 0);
- sobj = add_SOBJ(world->istg);
- while (get_line(strin, world)) {
- parse_word(name, 4, 1);
- if (verbose_flag>1) fprintf(stderr, "%s chunk.\n", name);
- if (strcmp(name, "NAME")==0) {
- parse_word(ps, 0, 0);
- strncpy(sobj->name, ps, 18);
- sobj->name[18] = '\0';
- } else if (strcmp(name, "STGF")==0) { sobj->stgf = get_UWORD();
- } else if (strcmp(name, "OSZ2")==0) { process_OSZ2(sobj, world);
- } else if (strcmp(name, "OSIZ")==0) { process_OSIZ(sobj, world);
- } else if (strcmp(name, "POS2")==0) { process_POS2(sobj, world);
- } else if (strcmp(name, "POSN")==0) { process_POSN(sobj, world);
- } else if (strcmp(name, "ALN2")==0) { process_ALN2(sobj, world);
- } else if (strcmp(name, "ALGN")==0) { process_ALGN(sobj, world);
- } else if (strcmp(name, "PALN")==0) { process_PALN(sobj, world);
- } else if (strcmp(name, "TALN")==0) { process_TALN(sobj, world);
- } else if (strcmp(name, "ASSC")==0) { process_ASSC(sobj, world);
- } else if (strcmp(name, "HING")==0) { process_HING(sobj, world);
- } else if (strcmp(name, "LYR0")==0) { process_LYR0(sobj);
- } else if (strcmp(name, "PTH2")==0) { process_PTH2(sobj, world);
- } else if (strcmp(name, "GLB3")==0) { process_GLB3(sobj, world);
- } else if (strcmp(name, "GLB2")==0) { process_GLB2(sobj, world);
- } else if (strcmp(name, "AXIS")==0) { process_AXIS(sobj, world);
- } else if (strcmp(name, "LIT2")==0) { process_LIT2(sobj, world);
- } else if (strcmp(name, "LITE")==0) { process_LITE(sobj, world);
- } else if (strcmp(name, "FIL3")==0) { process_FIL3(sobj, world);
- } else if (strcmp(name, "FILE")==0) { process_FILE(sobj, world);
- } else if (strcmp(name, "SPFX")==0) { process_SPFX(sobj, world, 0);
- } else if (strcmp(name, "S2FX")==0) { process_SPFX(sobj, world, 2);
- } else if (strcmp(name, "S3FX")==0) { process_SPFX(sobj, world, 3);
- } else if (strcmp(name, "S4FX")==0) { process_SPFX(sobj, world, 4);
- } else if (strcmp(name, "END")==0) {
- parse_word(name, 4, 1);
- if (strcmp(name, "SOBJ")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END SOBJ' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'SOBJ Begin' and 'End SOBJ' quoted comments do not match\n", world->cur_line);
- break;
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown SOBJ sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- continue;
- }
- }
- }
-
- /* Chunks unique to Imagine 2.0 */
- static void process_OSIZ(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register OSIZ *osiz;
-
- if (!(osiz = (OSIZ*)malloc(sizeof(OSIZ)))) OUT_MEM("OSIZ");
- bzero((char*)osiz, sizeof(OSIZ));
- osiz->chunk_type = OSIZ_CHUNK;
- osiz->start = osiz->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) osiz->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) osiz->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) osiz->stop = get_UWORD();
- else if (strcmp(name, "SIZE")==0) stuff_XYZ(&osiz->size);
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown OSIZ sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->osiz, (PALN*)osiz);
- }
-
- static void process_POSN(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register POSN *posn;
-
- if (!(posn = (POSN*)malloc(sizeof(POSN)))) OUT_MEM("POSN");
- bzero((char*)posn, sizeof(POSN));
- posn->chunk_type = POSN_CHUNK;
- posn->start = posn->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) posn->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) posn->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) posn->stop = get_UWORD();
- else if (strcmp(name, "POSN")==0) stuff_XYZ(&posn->posn);
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown POSN sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->posn, (PALN*)posn);
- }
-
- static void process_ALGN(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register ALGN *algn;
-
- if (!(algn = (ALGN*)malloc(sizeof(ALGN)))) OUT_MEM("ALGN");
- bzero((char*)algn, sizeof(ALGN));
- algn->chunk_type = ALGN_CHUNK;
- algn->start = algn->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) algn->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) algn->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) algn->stop = get_UWORD();
- else if (strcmp(name, "ALGN")==0) stuff_XYZ(&algn->algn);
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown ALGN sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->algn, (PALN*)algn);
- }
-
- static void process_HING(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register HING *hing;
-
- if (!(hing = (HING*)malloc(sizeof(HING)))) OUT_MEM("HING");
- bzero((char*)hing, sizeof(HING));
- hing->chunk_type = HING_CHUNK;
- hing->start = hing->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) hing->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) hing->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) hing->stop = get_UWORD();
- else if (strcmp(name, "NAME")==0) {
- parse_word(hing->hingeobj, 0, 0);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown HING sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->hing, (PALN*)hing);
- }
-
- static void process_GLB2(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[128];
- register GLB2 *glb2;
-
- if (!(glb2 = (GLB2*)malloc(sizeof(GLB2)))) OUT_MEM("GLB2");
- bzero((char*)glb2, sizeof(GLB2));
- glb2->chunk_type = GLB2_CHUNK;
- glb2->start = glb2->stop = 1;
- while (1) {
- parse_word(name, 0, 1); /* Don't limit the word size */
- if (!name[0]) break;
- if (strncmp(name, "FLAG",4)==0) glb2->flags = get_UWORD();
- else if (strcmp(name, "START")==0) glb2->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) glb2->stop = get_UWORD();
- else if (strncmp(name, "SKY_",4)==0) glb2->sky_blending = get_ULONG();
- else if (strncmp(name, "STARF",5)==0) glb2->starfield = get_FRACT();
- else if (strncmp(name, "TRAN",4)==0) glb2->transition = get_ULONG();
- /* The following are FRACTional colors */
- else if (strncmp(name, "AMBI",4)==0) stage_RGB(&glb2->ambient);
- else if (strncmp(name, "HORI",4)==0) stage_RGB(&glb2->horizon);
- else if (strcmp(name, "ZENITH1")==0) stage_RGB(&glb2->zenith1);
- else if (strcmp(name, "ZENITH2")==0) stage_RGB(&glb2->zenith2);
- else if (strncmp(name, "FOG_C",5)==0) stage_RGB(&glb2->fog_color);
- else if (strncmp(name, "FOG_B",5)==0) glb2->fog_bottom = get_FRACT();
- else if (strncmp(name, "FOG_T",5)==0) glb2->fog_top = get_FRACT();
- else if (strncmp(name, "FOG_L",5)==0) glb2->fog_length = get_FRACT();
- else if (strncmp(name, "BRUSH_S",7)==0) glb2->brush_seq = get_ULONG();
- else if (strncmp(name, "BACKDROP_S",10)==0) glb2->backdrop_seq = get_ULONG();
- else if (strcmp(name, "BACKDROP")==0) {
- parse_word(glb2->backdrop, 0, 0);
- } else if (strncmp(name, "GLOB",4)==0) {
- parse_word(glb2->globalbrush, 0, 0);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown PTH2 sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->glb2, (PALN*)glb2);
- }
-
- static void process_LITE(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register LITE *lite;
-
- if (!(lite = (LITE*)malloc(sizeof(LITE)))) OUT_MEM("LITE");
- bzero((char*)lite, sizeof(LITE));
- lite->chunk_type = LITE_CHUNK;
- lite->start = lite->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) lite->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) lite->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) lite->stop = get_UWORD();
- /* The following is a FRACTional color */
- else if (strcmp(name, "COLO")==0) stage_RGB(&lite->color);
- else if (strcmp(name, "TRAN")==0) lite->transition = get_ULONG();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown LITE sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->lite, (PALN*)lite);
- }
-
- static void process_FILE(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register SFILE *file;
-
- if (!(file = (SFILE*)malloc(sizeof(SFILE)))) OUT_MEM("SFILE");
- bzero((char*)file, sizeof(SFILE));
- file->chunk_type = SFILE_CHUNK;
- file->start = file->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) file->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) file->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) file->stop = get_UWORD();
- else if (strcmp(name, "CYCL")==0) file->cycles_to_perform = get_FRACT();
- else if (strcmp(name, "INIT")==0) file->initial_cycle_phase = get_FRACT();
- else if (strcmp(name, "TRAN")==0) file->transition = get_ULONG();
- else if (strcmp(name, "DESC")==0 || strcmp(name, "NAME")==0) {
- parse_word(file->object_description, 0, 0);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown FILE sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->file, (PALN*)file);
- }
-
- /* Chunks unique to Imagine 3.0 or common to both */
- static void process_OSZ2(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register OSZ2 *osz2;
-
- if (!(osz2 = (OSZ2*)malloc(sizeof(OSZ2)))) OUT_MEM("OSZ2");
- bzero((char*)osz2, sizeof(OSZ2));
- osz2->chunk_type = OSZ2_CHUNK;
- osz2->start = osz2->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) osz2->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) osz2->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) osz2->stop = get_UWORD();
- else if (strcmp(name, "SIZE")==0) stuff_XYZ(&osz2->size);
- else if (strcmp(name, "VEL0")==0) osz2->vel_0 = get_FRACT();
- else if (strcmp(name, "VEL1")==0) osz2->vel_1 = get_FRACT();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown OSZ2 sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->osz2, (PALN*)osz2);
- }
-
- static void process_POS2(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register POS2 *pos2;
-
- if (!(pos2 = (POS2*)malloc(sizeof(POS2)))) OUT_MEM("POS2");
- bzero((char*)pos2, sizeof(POS2));
- pos2->chunk_type = POS2_CHUNK;
- pos2->start = pos2->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) pos2->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) pos2->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) pos2->stop = get_UWORD();
- else if (strcmp(name, "POS2")==0) stuff_XYZ(&pos2->pos2);
- else if (strcmp(name, "VEL0")==0) pos2->vel_0 = get_FRACT();
- else if (strcmp(name, "VEL1")==0) pos2->vel_1 = get_FRACT();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown POS2 sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->pos2, (PALN*)pos2);
- }
-
- static void process_ALN2(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register ALN2 *aln2;
-
- if (!(aln2 = (ALN2*)malloc(sizeof(ALN2)))) OUT_MEM("ALN2");
- bzero((char*)aln2, sizeof(ALN2));
- aln2->chunk_type = ALN2_CHUNK;
- aln2->start = aln2->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) aln2->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) aln2->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) aln2->stop = get_UWORD();
- else if (strcmp(name, "ALN2")==0) stuff_XYZ(&aln2->aln2);
- else if (strcmp(name, "VEL0")==0) aln2->vel_0 = get_FRACT();
- else if (strcmp(name, "VEL1")==0) aln2->vel_1 = get_FRACT();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown ALN2 sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->aln2, (PALN*)aln2);
- }
-
- static void process_PALN(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register PALN *paln;
-
- if (!(paln = (PALN*)malloc(sizeof(PALN)))) OUT_MEM("PALN");
- bzero((char*)paln, sizeof(PALN));
- paln->chunk_type = PALN_CHUNK;
- paln->start = paln->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) paln->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) paln->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) paln->stop = get_UWORD();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown PALN sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list(&sobj->aln2, paln);
- }
-
- static void process_TALN(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register TALN *taln;
-
- if (!(taln = (TALN*)malloc(sizeof(TALN)))) OUT_MEM("TALN");
- bzero((char*)taln, sizeof(TALN));
- taln->chunk_type = TALN_CHUNK;
- taln->start = taln->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) taln->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) taln->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) taln->stop = get_UWORD();
- else if (strcmp(name, "INIT")==0) taln->initial_y = get_FRACT();
- else if (strcmp(name, "FINA")==0) taln->final_y = get_FRACT();
- else if (strcmp(name, "TRAC")==0 || strcmp(name, "NAME")==0 ||
- strcmp(name, "OBJE")==0) {
- parse_word(taln->trackobj, 0, 0);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown TALN sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->aln2, (PALN*)taln);
- }
-
- static void process_ASSC(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register ASSC *assc;
-
- if (!(assc = (ASSC*)malloc(sizeof(ASSC)))) OUT_MEM("ASSC");
- bzero((char*)assc, sizeof(assc));
- assc->chunk_type = ASSC_CHUNK;
- assc->start = assc->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) assc->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) assc->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) assc->stop = get_UWORD();
- else if (strcmp(name, "NAME")==0) {
- parse_word(assc->assc_obj, 0, 0);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown ASSC sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->assc, (PALN*)assc);
- }
-
- static void process_LYR0(sobj)
- SOBJ *sobj;
- {
- register LYR0 *lyr0;
-
- if (!(lyr0 = (LYR0*)malloc(sizeof(LYR0)))) OUT_MEM("LYR0");
- bzero((char*)lyr0, sizeof(LYR0));
- lyr0->chunk_type = LYR0_CHUNK;
- lyr0->layer = get_UWORD();
- insert_into_sorted_list((PALN**)&sobj->lyr0, (PALN*)lyr0);
- }
-
- static void process_PTH2(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[128];
- register PTH2 *pth2;
-
- if (!(pth2 = (PTH2*)malloc(sizeof(PTH2)))) OUT_MEM("PTH2");
- bzero((char*)pth2, sizeof(PTH2));
- pth2->chunk_type = PTH2_CHUNK;
- pth2->start = pth2->stop = 1;
- while (1) {
- parse_word(name, 0, 1); /* Don't limit the word size */
- if (!name[0]) break;
- if (strncmp(name, "FLAG",4)==0) pth2->flags = get_UWORD();
- else if (strcmp(name, "START")==0) pth2->start = get_UWORD();
- else if (strncmp(name, "STOP",4)==0) pth2->stop = get_UWORD();
- else if (strncmp(name, "ACCE",4)==0) pth2->acceleration_frames = get_ULONG();
- else if (strncmp(name, "START_",6)==0) pth2->start_speed=get_FRACT();
- else if (strncmp(name, "DECEL",5)==0) pth2->deacceleration_frames = get_ULONG();
- else if (strncmp(name, "END_",4)==0) pth2->end_speed = get_FRACT();
- else if (strcmp(name, "PATH")==0 || strcmp(name, "NAME")==0) {
- parse_word(pth2->path, 0, 0);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown PTH2 sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->pos2, (PALN*)pth2);
- }
-
- static void process_GLB3(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[128];
- register GLB3 *glb3;
-
- if (!(glb3 = (GLB3*)malloc(sizeof(GLB3)))) OUT_MEM("GLB3");
- bzero((char*)glb3, sizeof(GLB3));
- glb3->chunk_type = GLB3_CHUNK;
- glb3->start = glb3->stop = 1;
- while (1) {
- parse_word(name, 0, 1); /* Don't limit the word size */
- if (!name[0]) break;
- if (strncmp(name, "FLAG",4)==0) glb3->flags = get_UWORD();
- else if (strcmp(name, "START")==0) glb3->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) glb3->stop = get_UWORD();
- else if (strncmp(name, "STARF",5)==0) glb3->starfield = get_FRACT();
- else if (strncmp(name, "TRAN",4)==0) glb3->transition = get_ULONG();
- /* The following are FRACTional colors */
- else if (strncmp(name, "AMBI",4)==0) stage_RGB(&glb3->ambient);
- else if (strncmp(name, "HORI",4)==0) stage_RGB(&glb3->horizon);
- else if (strcmp(name, "ZENITH1")==0) stage_RGB(&glb3->zenith1);
- else if (strcmp(name, "ZENITH2")==0) stage_RGB(&glb3->zenith2);
- else if (strncmp(name, "FOG_C",5)==0) stage_RGB(&glb3->fog_color);
- else if (strncmp(name, "FOG_B",5)==0) glb3->fog_bottom = get_FRACT();
- else if (strncmp(name, "FOG_T",5)==0) glb3->fog_top = get_FRACT();
- else if (strncmp(name, "FOG_L",5)==0) glb3->fog_length = get_FRACT();
- else if (strncmp(name, "BRUSH_S",7)==0) glb3->brush_seq = get_ULONG();
- else if (strncmp(name, "BACKDROP_S",10)==0) glb3->backdrop_seq = get_ULONG();
- else if (strcmp(name, "BACKDROP")==0) {
- parse_word(glb3->backdrop, 0, 0);
- } else if (strncmp(name, "GLOB",4)==0) {
- parse_word(glb3->globalbrush, 0, 0);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown GLB3 sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->glb3, (PALN*)glb3);
- }
-
- static void process_AXIS(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register SAXIS *axis;
-
- if (!(axis = (SAXIS*)malloc(sizeof(SAXIS)))) OUT_MEM("SAXIS");
- bzero((char*)axis, sizeof(SAXIS));
- axis->chunk_type = SAXIS_CHUNK;
- axis->start = axis->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) axis->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) axis->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) axis->stop = get_UWORD();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown AXIS sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->axis, (PALN*)axis);
- }
-
- static void process_LIT2(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register LIT2 *lit2;
-
- if (!(lit2 = (LIT2*)malloc(sizeof(LIT2)))) OUT_MEM("LIT2");
- bzero((char*)lit2, sizeof(LIT2));
- lit2->chunk_type = LIT2_CHUNK;
- lit2->start = lit2->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) lit2->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) lit2->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) lit2->stop = get_UWORD();
- /* The following is a FRACTional color */
- else if (strcmp(name, "COLO")==0) stage_RGB(&lit2->color);
- else if (strcmp(name, "TRAN")==0) lit2->transition = get_ULONG();
- else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown LIT2 sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->lit2, (PALN*)lit2);
- }
-
- static void process_FIL3(sobj, world)
- SOBJ *sobj;
- WORLD *world;
- {
- char name[5];
- register FIL3 *fil3;
-
- if (!(fil3 = (FIL3*)malloc(sizeof(FIL3)))) OUT_MEM("FIL3");
- bzero((char*)fil3, sizeof(FIL3));
- fil3->chunk_type = FIL3_CHUNK;
- fil3->start = fil3->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) fil3->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) fil3->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) fil3->stop = get_UWORD();
- else if (strcmp(name, "CYCL")==0) fil3->cycles_to_perform = get_FRACT();
- else if (strcmp(name, "INIT")==0) fil3->initial_cycle_phase = get_FRACT();
- else if (strcmp(name, "VEL0")==0) fil3->vel_0 = get_FRACT();
- else if (strcmp(name, "VEL1")==0) fil3->vel_1 = get_FRACT();
- else if (strcmp(name, "STAT")==0) parse_word(fil3->state, 0, 0);
- else if (strcmp(name, "DESC")==0 || strcmp(name, "NAME")==0) {
- parse_word(fil3->object_description, 0, 0);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown FIL3 sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- insert_into_sorted_list((PALN**)&sobj->fil3, (PALN*)fil3);
- }
-
- static void process_SPFX(sobj, world, index)
- SOBJ *sobj;
- WORLD *world;
- int index;
- {
- char name[5];
- register SPFX *spfx;
-
- if (!(spfx = (SPFX*)malloc(sizeof(SPFX)))) OUT_MEM("SPFX");
- bzero((char*)spfx, sizeof(SPFX));
- spfx->chunk_type = SPFX_CHUNK;
- spfx->start = spfx->stop = 1;
- while (1) {
- parse_word(name, 4, 1);
- if (!name[0]) break;
- if (strcmp(name, "FLAG")==0) spfx->flags = get_UWORD();
- else if (strcmp(name, "STAR")==0) spfx->start = get_UWORD();
- else if (strcmp(name, "STOP")==0) spfx->stop = get_UWORD();
- else if (strcmp(name, "NAME")==0) {
- parse_word(spfx->effect, 0, 0);
- }
- else if (strcmp(name, "DATA")==0) {
- parse_effect_data(spfx->effect_data);
- } else {
- if (verbose_flag)
- fprintf(stderr, "WARNING: Line %d: Unknown FIL3 sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
- switch (index) {
- case 0:
- insert_into_sorted_list((PALN**)&sobj->spfx, (PALN*)spfx);
- break;
- case 2:
- insert_into_sorted_list((PALN**)&sobj->s2fx, (PALN*)spfx);
- break;
- case 3:
- insert_into_sorted_list((PALN**)&sobj->s3fx, (PALN*)spfx);
- break;
- case 4:
- insert_into_sorted_list((PALN**)&sobj->s4fx, (PALN*)spfx);
- }
- }
-
-